<template>
  <el-form
    ref="formRef"
    :model="props.formData"
    :rules="props.formRules"
    v-bind="$attrs"
  >
    <el-row :gutter="props.gutter">
      <el-col
        v-for="(column, index) in props.formColumns"
        :key="index"
        :span="column.span"
        :offset="column.offset"
      >
        <template v-if="column.submit">
          <slot :name="column.submit"></slot>
        </template>
        <el-form-item
          v-else
          :label="column.label"
          :label-width="column.labelWidth ? column.labelWidth + 'px' : '120px'"
          :prop="column.prop"
          v-bind="column.formItemOpts"
        >
          <template #label>
            <slot
              :name="column.labelSlot"
              :column="{ ...column }"
              :data="{ ...formData }"
            />
          </template>
          <slot
            v-if="column.xType === 'Slot'"
            :name="column.slotName"
            :column="{ ...column }"
            :data="{ ...formData }"
          ></slot>

          <template v-else>
            <component
              :is="componentsTypes[column.xType]"
              v-bind="column"
              v-model="props.formData[column.prop]"
            >
            </component>
            <!--formItem下增加插槽-->
            <slot
              v-if="column.formItemSlot"
              :name="column.formItemSlot"
              :column="{ ...column }"
              :data="{ ...formData }"
            ></slot>
          </template>
        </el-form-item>
      </el-col>
      <el-col v-if="slotShow">
        <slot>
          <!-- 操作按钮 -->
          <div
            class="submitBox"
            style="text-align: center; padding-bottom: 18px"
          >
            <el-button type="primary" @click="onSubmit(formRef)"
              >提交</el-button
            >
            <el-button @click="handlerReset(formRef)">重置</el-button>
          </div>
        </slot>
      </el-col>
    </el-row>
  </el-form>
</template>
<script lang="ts">
export default {
  name: "MyForm",
};
</script>
<script lang="ts" setup>
import { ref, markRaw } from "vue";
import Input from "./PengInput.vue"; // Input 入框
import Autocomplete from "./PengAutocomplete.vue"; // Autocomplete 自动补全输入框
import Select from "./PengSelect.vue"; // Select 下拉框
import SelectV2 from "./PengSelectV2.vue"; // Select V2 虚拟列表选择器
import DatePicker from "./PengDatePicker.vue"; // DatePicker 日期时间选择器
import TimePicker from "./PengTimePicker.vue"; // TimePicker 时间选择器
import TimeSelect from "./PengTimeSelect.vue"; // TimeSelect 时间选择
import InputNumber from "./PengInputNumber.vue"; // InputNumber 数字输入框
import Radio from "./PengRadio.vue"; // Radio 单选框
import Checkbox from "./PengCheckbox.vue"; // Checkbox 多选框
import Switch from "./PengSwitch.vue"; // Switch 开关
import Slider from "./PengSlider.vue"; // Slider 滑块
import Rate from "./PengRate.vue"; // Rate 评分
import Transfer from "./PengTransfer.vue"; // Transfer 穿梭框
import Cascader from "./PengCascader.vue"; // Cascader 级联框
import ColorPicker from "./PengColorPicker.vue"; // ColorPicker 颜色选择器
import Tree from "./PengTree.vue"; // Tree 树形控件
import TreeSelect from "./PengTreeSelect.vue"; // TreeSelect 树形选择
import TreeV2 from "./PengTreeV2.vue"; // Tree V2 虚拟化树形控件
import {formatDate} from "@/utils/index";
const props = defineProps({
  // 表单数据
  formData: {
    type: Object,
    default: () => {},
  },
  // 表单配置项
  formColumns: {
    type: Array as any,
    default: () => [],
  },
  // 表单规则验证
  formRules: {
    type: Object,
    default: () => {},
  },
  slotShow: {
    type: Boolean,
    default: true,
  },
  // 表单元素间隔
  gutter: {
    type: Number,
    default: 20
  }
});
// 定义动态组件
const componentsTypes = markRaw({
  Input, // input输入框
  Autocomplete,
  Select, // 下拉输入框
  SelectV2, // 虚拟列表
  DatePicker, // 年月日
  TimePicker, // 时分秒
  TimeSelect, // 时间选择
  InputNumber, // 数字输入框
  Radio, // 单选
  Checkbox, // 多选
  Switch, // switch
  Slider, // 取值范围
  Rate, // 评分
  Transfer, // 穿梭框
  Cascader, // 级联选择器
  ColorPicker, // 颜色选择器
  Tree, // 树形控件
  TreeSelect, // 树形选择
  TreeV2, // 虚拟树形控件
}) as any;


watch(
  () => props.formData,
  (newVal) => {
    // 统一处理日期时间问题
    formatDateHandle(newVal)
  },
  { deep: true }
);

// 统一处理日期时间问题
const formatDateHandle = (val: any) =>{
  formatDate(props.formColumns, val)
}

// 将表单绑定的ref暴露给父组件
const formRef = ref<any>(null);

const emit = defineEmits(["onSubmit", "onReset"]);

// 提交按钮触发-提交操作
async function onSubmit(formEl: any) {
  if (!formEl) return;
  await formEl.validate((valid: boolean) => {
    if (!valid) return;
    emit("onSubmit");
  });
}

// 重置按钮触发-重置操作
function handlerReset(formEl: any) {
  if (!formEl) return;
  formEl.resetFields();
  emit("onReset");
}

// 无按钮操作：提交校验
async function formSubmit() {
  if (!formRef) {
    return false;
  }
  return await formRef.value.validate((valid: boolean) => {
    if (!valid) return false;
    return true;
  });
}

// 无按钮操作：重置表单
function formReset() {
  if (!formRef) return false;
  formRef.value.resetFields();
  return true;
}

defineExpose({ formRef, onSubmit, handlerReset, formSubmit, formReset });
</script>
